#include "webapi_amap_location.h"

#include <ArduinoJson.h>
#include <IPAddress.h>
#include <stdio.h>

#include "webapi_http_utils.h"

namespace webapi {

bool AmapLocationService::QueryPublicIpAddress(IPAddress& ipAddress) {
  String content;
  if (!HttpGet("http://api.ipify.org", content)) {
    Serial.println("Request to http://api.ipify.org FAILED!");
  }
  return ipAddress.fromString(content);
}

bool AmapLocationService::QueryGeoLocation(AmapLocation& response,
                                           const IPAddress& ipAddress) {
  char geoLocURL[128] = "";
  snprintf(geoLocURL, sizeof(geoLocURL),
           "http://restapi.amap.com/v3/ip?key=%s&ip=%s", this->GetAmapApiKey(),
           ipAddress.toString().c_str());

  String content;
  if (!HttpGet(geoLocURL, content)) {
    Serial.println("Request to http://restapi.amap.com/v3/ip FAILED!");
    return false;
  }

  JsonDocument doc;
  if (auto error = deserializeJson(doc, content)) {
    Serial.println("Parse response from http://restapi.amap.com/v3/ip FAILED!");
    return false;
  }

  response.status = doc["status"].as<int>();
  response.info = doc["info"].as<const char*>();
  response.infocode = doc["infocode"].as<int>();

  response.province = doc["province"].as<const char*>();
  response.city = doc["city"].as<const char*>();
  response.adcode = doc["adcode"].as<int>();

  GeoLocation leftUp;
  GeoLocation rightDown;
  String rectangle = doc["rectangle"];
  sscanf(rectangle.c_str(), "%f,%f;%f,%f", &leftUp.longitude, &leftUp.latitude,
         &rightDown.longitude, &rightDown.latitude);

  response.rectangle.leftUp = leftUp;
  response.rectangle.rightDown = rightDown;

  Serial.println("Recv response success!");
  Serial.printf("status: %d\r\n", response.status);
  Serial.printf("info: %s\r\n", response.info.c_str());
  Serial.printf("infocode: %d\r\n", response.infocode);

  Serial.printf("province: %s\r\n", response.province.c_str());
  Serial.printf("city: %s\r\n", response.city.c_str());
  Serial.printf("adcode: %d\r\n", response.adcode);

  return true;
}

bool AmapLocationService::QueryGeoLocation(AmapLocation& locResponse) {
  IPAddress ipAddress{};
  if (!QueryPublicIpAddress(ipAddress)) {
    return false;
  }
  return QueryGeoLocation(locResponse, ipAddress);
}

}  // namespace webapi